// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only

#include <QString>
#include <QList>
#include <map>

extern "C" {
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#include <X11/XF86keysym.h>
#include <ctime>
}

static const std::map<QString, quint32> unicodeKeySymbolsForAtspi {
        {"!",0x0021}, {"#",0x0023}, {"%",0x0025}, {"&",0x0026}, {"'",0x0027},
        {"(",0x0028}, {")",0x0029}, {"*",0x002A}, {"+",0x002B}, {",",0x002C}, {"-",0x002D}, {".",0x002E},
        {"0",0x0030}, {"1",0x0031}, {"2",0x0032}, {"3",0x0033}, {"4",0x0034}, {"5",0x0035}, {"6",0x0036},
        {"7",0x0037}, {"8",0x0038}, {"9",0x0039}, {":",0x003A}, {";",0x003B}, {"<",0x003C}, {"/",0x002F},
        {"=",0x003D}, {">",0x003E}, {"?",0x003F}, {"A",0x0041}, {"B",0x0042}, {"C",0x0043},
        {"D",0x0044}, {"E",0x0045}, {"F",0x0046}, {"G",0x0047}, {"H",0x0048}, {"I",0x0049}, {"J",0x004A},
        {"K",0x004B}, {"L",0x004C}, {"M",0x004D}, {"N",0x004E}, {"O",0x004F}, {"P",0x0050}, {"Q",0x0051},
        {"R",0x0052}, {"S",0x0053}, {"T",0x0054}, {"U",0x0055}, {"V",0x0056}, {"W",0x0057}, {"X",0x0058},
        {"Y",0x0059}, {"Z",0x005A}, {"_",0x005F},
        {"a",0x0061}, {"b",0x0062}, {"c",0x0063}, {"d",0x0064}, {"e",0x0065}, {"f",0x0066},
        {"g",0x0067}, {"h",0x0068}, {"i",0x0069}, {"j",0x006A}, {"k",0x006B}, {"l",0x006C}, {"m",0x006D},
        {"n",0x006E}, {"o",0x006F}, {"p",0x0070}, {"q",0x0071}, {"r",0x0072}, {"s",0x0073}, {"t",0x0074},
        {"u",0x0075}, {"v",0x0076}, {"w",0x0077}, {"x",0x0078}, {"y",0x0079}, {"z",0x007A},
};

static const std::map<QString, quint32> unicodeKeySymbols {
    {"=",0x003D}, {">",0x003E}, {"?",0x003F}, {"@",0x0040}, {"^",0x005E},
    {"|",0x007C}, {"}",0x007D}, {"~",0x007E}, {" ",0x00A0}, {"¡",0x00A1}, {"¢",0x00A2}, {"£",0x00A3},
    {"¤",0x00A4}, {"¥",0x00A5}, {"¦",0x00A6}, {"§",0x00A7}, {"¨",0x00A8}, {"©",0x00A9}, {"ª",0x00AA},
    {"«",0x00AB}, {"¬",0x00AC}, {"­",0x00AD}, {"®",0x00AE}, {"¯",0x00AF}, {"°",0x00B0}, {"±",0x00B1},
    {"²",0x00B2}, {"³",0x00B3}, {"´",0x00B4}, {"µ",0x00B5}, {"¶",0x00B6}, {"·",0x00B7}, {"¸",0x00B8},
    {"¹",0x00B9}, {"º",0x00BA}, {"»",0x00BB}, {"¼",0x00BC}, {"½",0x00BD}, {"¾",0x00BE},
    {"¿",0x00BF},
    {"À",0x00C0}, {"Á",0x00C1}, {"Â",0x00C2}, {"Ã",0x00C3}, {"Ä",0x00C4}, {"Å",0x00C5}, {"Æ",0x00C6},
    {"Ç",0x00C7}, {"È",0x00C8}, {"É",0x00C9}, {"Ê",0x00CA}, {"Ë",0x00CB}, {"Ì",0x00CC}, {"Í",0x00CD},
    {"Î",0x00CE}, {"Ï",0x00CF}, {"Ð",0x00D0}, {"Ñ",0x00D1}, {"Ò",0x00D2}, {"Ó",0x00D3}, {"Ô",0x00D4},
    {"Õ",0x00D5}, {"Ö",0x00D6}, {"×",0x00D7}, {"Ø",0x00D8}, {"Ù",0x00D9}, {"Ú",0x00DA}, {"Û",0x00DB},
    {"Ü",0x00DC}, {"Ý",0x00DD}, {"Þ",0x00DE}, {"ß",0x00DF}, {"à",0x00E0}, {"á",0x00E1}, {"â",0x00E2},
    {"ã",0x00E3}, {"ä",0x00E4}, {"å",0x00E5}, {"æ",0x00E6}, {"ç",0x00E7}, {"è",0x00E8}, {"é",0x00E9},
    {"ê",0x00EA}, {"ë",0x00EB}, {"ì",0x00EC}, {"í",0x00ED}, {"î",0x00EE}, {"ï",0x00EF}, {"ð",0x00F0},
    {"ñ",0x00F1}, {"ò",0x00F2}, {"ó",0x00F3}, {"ô",0x00F4}, {"õ",0x00F5}, {"ö",0x00F6}, {"÷",0x00F7},
    {"ø",0x00F8}, {"ù",0x00F9}, {"ú",0x00FA}, {"û",0x00FB}, {"ü",0x00FC}, {"ý",0x00FD}, {"þ",0x00FE},
    {"ÿ",0x00FF}, {"Ą",0x01A1}, {"˘",0x01A2}, {"Ł",0x01A3}, {"Ľ",0x01A5}, {"Ś",0x01A6}, {"Š",0x01A9},
    {"Ş",0x01AA}, {"Ť",0x01AB}, {"Ź",0x01AC}, {"Ž",0x01AE}, {"Ż",0x01AF}, {"ą",0x01B1}, {"˛",0x01B2},
    {"ł",0x01B3}, {"ľ",0x01B5}, {"ś",0x01B6}, {"ˇ",0x01B7}, {"š",0x01B9}, {"ş",0x01BA}, {"ť",0x01BB},
    {"ź",0x01BC}, {"˝",0x01BD}, {"ž",0x01BE}, {"ż",0x01BF}, {"Ŕ",0x01C0}, {"Ă",0x01C3}, {"Ĺ",0x01C5},
    {"Ć",0x01C6}, {"Č",0x01C8}, {"Ę",0x01CA}, {"Ě",0x01CC}, {"Ď",0x01CF}, {"Đ",0x01D0}, {"Ń",0x01D1},
    {"Ň",0x01D2}, {"Ő",0x01D5}, {"Ř",0x01D8}, {"Ů",0x01D9}, {"Ű",0x01DB}, {"Ţ",0x01DE}, {"ŕ",0x01E0},
    {"ă",0x01E3}, {"ĺ",0x01E5}, {"ć",0x01E6}, {"č",0x01E8}, {"ę",0x01EA}, {"ě",0x01EC}, {"ď",0x01EF},
    {"đ",0x01F0}, {"ń",0x01F1}, {"ň",0x01F2}, {"ő",0x01F5}, {"ř",0x01F8}, {"ů",0x01F9}, {"ű",0x01FB},
    {"ţ",0x01FE}, {"˙",0x01FF}, {"Ħ",0x02A1}, {"Ĥ",0x02A6}, {"İ",0x02A9}, {"Ğ",0x02AB}, {"Ĵ",0x02AC},
    {"ħ",0x02B1}, {"ĥ",0x02B6}, {"ı",0x02B9}, {"ğ",0x02BB}, {"ĵ",0x02BC}, {"Ċ",0x02C5}, {"Ĉ",0x02C6},
    {"Ġ",0x02D5}, {"Ĝ",0x02D8}, {"Ŭ",0x02DD}, {"?Ŝ",0x02DE}, {"ċ",0x02E5}, {"ĉ",0x02E6}, {"ġ",0x02F5},
    {"ĝ",0x02F8}, {"ŭ",0x02FD}, {"ŝ",0x02FE}, {"ĸ",0x03A2}, {"Ŗ",0x03A3}, {"Ĩ",0x03A5}, {"Ļ",0x03A6},
    {"Ē",0x03AA}, {"Ģ",0x03AB}, {"Ŧ",0x03AC}, {"ŗ",0x03B3}, {"ĩ",0x03B5}, {"ļ",0x03B6}, {"ē",0x03BA},
    {"ģ",0x03BB}, {"ŧ",0x03BC}, {"Ŋ",0x03BD}, {"ŋ",0x03BF}, {"Ā",0x03C0}, {"Į",0x03C7}, {"Ė",0x03CC},
    {"Ī",0x03CF}, {"Ņ",0x03D1}, {"Ō",0x03D2}, {"Ķ",0x03D3}, {"Ų",0x03D9}, {"Ũ",0x03DD}, {"Ū",0x03DE},
    {"ā",0x03E0}, {"į",0x03E7}, {"ė",0x03EC}, {"ī",0x03EF}, {"ņ",0x03F1}, {"ō",0x03F2}, {"ķ",0x03F3},
    {"ų",0x03F9}, {"ũ",0x03FD}, {"ū",0x03FE}, {"‾",0x047E}, {"。",0x04A1}, {"「",0x04A2}, {"」",0x04A3},
    {"、",0x04A4}, {"・",0x04A5}, {"ヲ",0x04A6}, {"ァ",0x04A7}, {"ィ",0x04A8}, {"ゥ",0x04A9}, {"ェ",0x04AA},
    {"ォ",0x04AB}, {"ャ",0x04AC}, {"ュ",0x04AD}, {"ョ",0x04AE}, {"ッ",0x04AF}, {"ー",0x04B0}, {"ア",0x04B1},
    {"イ",0x04B2}, {"ウ",0x04B3}, {"エ",0x04B4}, {"オ",0x04B5}, {"カ",0x04B6}, {"キ",0x04B7}, {"ク",0x04B8},
    {"ケ",0x04B9}, {"コ",0x04BA}, {"サ",0x04BB}, {"シ",0x04BC}, {"ス",0x04BD}, {"セ",0x04BE}, {"ソ",0x04BF},
    {"タ",0x04C0}, {"チ",0x04C1}, {"ツ",0x04C2}, {"テ",0x04C3}, {"ト",0x04C4}, {"ナ",0x04C5}, {"ニ",0x04C6},
    {"ヌ",0x04C7}, {"ネ",0x04C8}, {"ノ",0x04C9}, {"ハ",0x04CA}, {"ヒ",0x04CB}, {"フ",0x04CC}, {"ヘ",0x04CD},
    {"ホ",0x04CE}, {"マ",0x04CF}, {"ミ",0x04D0}, {"ム",0x04D1}, {"メ",0x04D2}, {"モ",0x04D3}, {"ヤ",0x04D4},
    {"ユ",0x04D5}, {"ヨ",0x04D6}, {"ラ",0x04D7}, {"リ",0x04D8}, {"ル",0x04D9}, {"レ",0x04DA}, {"ロ",0x04DB},
    {"ワ",0x04DC}, {"ン",0x04DD}, {"゛",0x04DE}, {"゜",0x04DF}, {"۰",0x0590}, {"۱",0x0591}, {"۲",0x0592},
    {"۳",0x0593}, {"۴",0x0594}, {"۵",0x0595}, {"۶",0x0596}, {"۷",0x0597}, {"۸",0x0598}, {"۹",0x0599},
    {"٪",0x05A5}, {"ٰ",0x05A6}, {"ٹ",0x05A7}, {"پ",0x05A8}, {"چ",0x05A9}, {"ڈ",0x05AA}, {"ڑ",0x05AB},
    {"،",0x05AC}, {"۔",0x05AE}, {"٠",0x05B0}, {"١",0x05B1}, {"٢",0x05B2}, {"٣",0x05B3}, {"٤",0x05B4},
    {"٥",0x05B5}, {"٦",0x05B6}, {"٧",0x05B7}, {"٨",0x05B8}, {"٩",0x05B9}, {"؛",0x05BB}, {"؟",0x05BF},
    {"ء",0x05C1}, {"آ",0x05C2}, {"أ",0x05C3}, {"ؤ",0x05C4}, {"إ",0x05C5}, {"ئ",0x05C6}, {"ا",0x05C7},
    {"ب",0x05C8}, {"ة",0x05C9}, {"ت",0x05CA}, {"ث",0x05CB}, {"ج",0x05CC}, {"ح",0x05CD}, {"خ",0x05CE},
    {"د",0x05CF}, {"ذ",0x05D0}, {"ر",0x05D1}, {"ز",0x05D2}, {"س",0x05D3}, {"ش",0x05D4}, {"ص",0x05D5},
    {"ض",0x05D6}, {"ط",0x05D7}, {"ظ",0x05D8}, {"ع",0x05D9}, {"غ",0x05DA}, {"ـ",0x05E0}, {"ف",0x05E1},
    {"ق",0x05E2}, {"ك",0x05E3}, {"ل",0x05E4}, {"م",0x05E5}, {"ن",0x05E6}, {"ه",0x05E7}, {"و",0x05E8},
    {"ى",0x05E9}, {"ي",0x05EA}, {"ً",0x05EB}, {"ٌ",0x05EC}, {"ٍ",0x05ED}, {"َ",0x05EE}, {"ُ",0x05EF},
    {"ِ",0x05F0}, {"ّ",0x05F1}, {"ْ",0x05F2}, {"ٓ",0x05F3}, {"ٔ",0x05F4}, {"ٕ",0x05F5}, {"ژ",0x05F6},
    {"ڤ",0x05F7}, {"ک",0x05F8}, {"گ",0x05F9}, {"ں",0x05FA}, {"ھ",0x05FB}, {"ی",0x05FC}, {"ے",0x05FD},
    {"ہ",0x05FE}, {"Ғ",0x0680}, {"Җ",0x0681}, {"Қ",0x0682}, {"Ҝ",0x0683}, {"Ң",0x0684}, {"Ү",0x0685},
    {"Ұ",0x0686}, {"Ҳ",0x0687}, {"Ҷ",0x0688}, {"Ҹ",0x0689}, {"Һ",0x068A}, {"Ә",0x068C}, {"Ӣ",0x068D},
    {"Ө",0x068E}, {"Ӯ",0x068F}, {"ғ",0x0690}, {"җ",0x0691}, {"қ",0x0692}, {"ҝ",0x0693}, {"ң",0x0694},
    {"ү",0x0695}, {"ұ",0x0696}, {"ҳ",0x0697}, {"ҷ",0x0698}, {"ҹ",0x0699}, {"һ",0x069A}, {"ә",0x069C},
    {"ӣ",0x069D}, {"ө",0x069E}, {"ӯ",0x069F}, {"ђ",0x06A1}, {"ѓ",0x06A2}, {"ё",0x06A3}, {"є",0x06A4},
    {"ѕ",0x06A5}, {"і",0x06A6}, {"ї",0x06A7}, {"ј",0x06A8}, {"љ",0x06A9}, {"њ",0x06AA}, {"ћ",0x06AB},
    {"ќ",0x06AC}, {"ґ",0x06AD}, {"ў",0x06AE}, {"џ",0x06AF}, {"№",0x06B0}, {"Ђ",0x06B1}, {"Ѓ",0x06B2},
    {"Ё",0x06B3}, {"Є",0x06B4}, {"Ѕ",0x06B5}, {"І",0x06B6}, {"Ї",0x06B7}, {"Ј",0x06B8}, {"Љ",0x06B9},
    {"Њ",0x06BA}, {"Ћ",0x06BB}, {"Ќ",0x06BC}, {"Ґ",0x06BD}, {"Ў",0x06BE}, {"Џ",0x06BF}, {"ю",0x06C0},
    {"а",0x06C1}, {"б",0x06C2}, {"ц",0x06C3}, {"д",0x06C4}, {"е",0x06C5}, {"ф",0x06C6}, {"г",0x06C7},
    {"х",0x06C8}, {"и",0x06C9}, {"й",0x06CA}, {"к",0x06CB}, {"л",0x06CC}, {"м",0x06CD}, {"н",0x06CE},
    {"о",0x06CF}, {"п",0x06D0}, {"я",0x06D1}, {"р",0x06D2}, {"с",0x06D3}, {"т",0x06D4}, {"у",0x06D5},
    {"ж",0x06D6}, {"в",0x06D7}, {"ь",0x06D8}, {"ы",0x06D9}, {"з",0x06DA}, {"ш",0x06DB}, {"э",0x06DC},
    {"щ",0x06DD}, {"ч",0x06DE}, {"ъ",0x06DF}, {"Ю",0x06E0}, {"А",0x06E1}, {"Б",0x06E2}, {"Ц",0x06E3},
    {"Д",0x06E4}, {"Е",0x06E5}, {"Ф",0x06E6}, {"Г",0x06E7}, {"Х",0x06E8}, {"И",0x06E9}, {"Й",0x06EA},
    {"К",0x06EB}, {"Л",0x06EC}, {"М",0x06ED}, {"Н",0x06EE}, {"О",0x06EF}, {"П",0x06F0}, {"Я",0x06F1},
    {"Р",0x06F2}, {"С",0x06F3}, {"Т",0x06F4}, {"У",0x06F5}, {"Ж",0x06F6}, {"В",0x06F7}, {"Ь",0x06F8},
    {"Ы",0x06F9}, {"З",0x06FA}, {"Ш",0x06FB}, {"Э",0x06FC}, {"Щ",0x06FD}, {"Ч",0x06FE}, {"Ъ",0x06FF},
    {"Ά",0x07A1}, {"Έ",0x07A2}, {"Ή",0x07A3}, {"Ί",0x07A4}, {"Ϊ",0x07A5}, {"Ό",0x07A7}, {"Ύ",0x07A8},
    {"Ϋ",0x07A9}, {"Ώ",0x07AB}, {"΅",0x07AE}, {"―",0x07AF}, {"ά",0x07B1}, {"έ",0x07B2}, {"ή",0x07B3},
    {"ί",0x07B4}, {"ϊ",0x07B5}, {"ΐ",0x07B6}, {"ό",0x07B7}, {"ύ",0x07B8}, {"ϋ",0x07B9}, {"ΰ",0x07BA},
    {"ώ",0x07BB}, {"Α",0x07C1}, {"Β",0x07C2}, {"Γ",0x07C3}, {"Δ",0x07C4}, {"Ε",0x07C5}, {"Ζ",0x07C6},
    {"Η",0x07C7}, {"Θ",0x07C8}, {"Ι",0x07C9}, {"Κ",0x07CA}, {"Λ",0x07CB}, {"Μ",0x07CC}, {"Ν",0x07CD},
    {"Ξ",0x07CE}, {"Ο",0x07CF}, {"Π",0x07D0}, {"Ρ",0x07D1}, {"Σ",0x07D2}, {"Τ",0x07D4}, {"Υ",0x07D5},
    {"Φ",0x07D6}, {"Χ",0x07D7}, {"Ψ",0x07D8}, {"Ω",0x07D9}, {"α",0x07E1}, {"β",0x07E2}, {"γ",0x07E3},
    {"δ",0x07E4}, {"ε",0x07E5}, {"ζ",0x07E6}, {"η",0x07E7}, {"θ",0x07E8}, {"ι",0x07E9}, {"κ",0x07EA},
    {"λ",0x07EB}, {"μ",0x07EC}, {"ν",0x07ED}, {"ξ",0x07EE}, {"ο",0x07EF}, {"π",0x07F0}, {"ρ",0x07F1},
    {"σ",0x07F2}, {"ς",0x07F3}, {"τ",0x07F4}, {"υ",0x07F5}, {"φ",0x07F6}, {"χ",0x07F7}, {"ψ",0x07F8},
    {"ω",0x07F9}, {"⎷",0x08A1}, {"┌",0x08A2}, {"─",0x08A3}, {"⌠",0x08A4}, {"⌡",0x08A5}, {"│",0x08A6},
    {"⎡",0x08A7}, {"⎣",0x08A8}, {"⎤",0x08A9}, {"⎦",0x08AA}, {"⎛",0x08AB}, {"⎝",0x08AC}, {"⎞",0x08AD},
    {"⎠",0x08AE}, {"⎨",0x08AF}, {"⎬",0x08B0}, {"≤",0x08BC}, {"≠",0x08BD}, {"≥",0x08BE}, {"∫",0x08BF},
    {"∴",0x08C0}, {"∝",0x08C1}, {"∞",0x08C2}, {"∇",0x08C5}, {"∼",0x08C8}, {"≃",0x08C9}, {"⇔",0x08CD},
    {"⇒",0x08CE}, {"≡",0x08CF}, {"√",0x08D6}, {"⊂",0x08DA}, {"⊃",0x08DB}, {"∩",0x08DC}, {"∪",0x08DD},
    {"∧",0x08DE}, {"∨",0x08DF}, {"∂",0x08EF}, {"ƒ",0x08F6}, {"←",0x08FB}, {"↑",0x08FC}, {"→",0x08FD},
    {"↓",0x08FE}, {"◆",0x09E0}, {"▒",0x09E1}, {"␉",0x09E2}, {"␌",0x09E3}, {"␍",0x09E4}, {"␊",0x09E5},
    {"␤",0x09E8}, {"␋",0x09E9}, {"┘",0x09EA}, {"┐",0x09EB}, {"┌",0x09EC}, {"└",0x09ED}, {"┼",0x09EE},
    {"⎺",0x09EF}, {"⎻",0x09F0}, {"─",0x09F1}, {"⎼",0x09F2}, {"⎽",0x09F3}, {"├",0x09F4}, {"┤",0x09F5},
    {"┴",0x09F6}, {"┬",0x09F7}, {"│",0x09F8}, {" ",0x0AA1}, {" ",0x0AA2}, {" ",0x0AA3}, {" ",0x0AA4},
    {" ",0x0AA5}, {" ",0x0AA6}, {" ",0x0AA7}, {" ",0x0AA8}, {"—",0x0AA9}, {"–",0x0AAA}, {"␣",0x0AAC},
    {"…",0x0AAE}, {"‥",0x0AAF}, {"⅓",0x0AB0}, {"⅔",0x0AB1}, {"⅕",0x0AB2}, {"⅖",0x0AB3}, {"⅗",0x0AB4},
    {"⅘",0x0AB5}, {"⅙",0x0AB6}, {"⅚",0x0AB7}, {"℅",0x0AB8}, {"‒",0x0ABB}, {"⟨",0x0ABC}, {".",0x0ABD},
    {"⟩",0x0ABE}, {"⅛",0x0AC3}, {"⅜",0x0AC4}, {"⅝",0x0AC5}, {"⅞",0x0AC6}, {"™",0x0AC9}, {"☓",0x0ACA},
    {"◁",0x0ACC}, {"▷",0x0ACD}, {"○",0x0ACE}, {"▯",0x0ACF}, {"‘",0x0AD0}, {"’",0x0AD1}, {"“",0x0AD2},
    {"”",0x0AD3}, {"℞",0x0AD4}, {"′",0x0AD6}, {"″",0x0AD7}, {"✝",0x0AD9}, {"▬",0x0ADB}, {"◀",0x0ADC},
    {"▶",0x0ADD}, {"●",0x0ADE}, {"▮",0x0ADF}, {"◦",0x0AE0}, {"▫",0x0AE1}, {"▭",0x0AE2}, {"△",0x0AE3},
    {"▽",0x0AE4}, {"☆",0x0AE5}, {"•",0x0AE6}, {"▪",0x0AE7}, {"▲",0x0AE8}, {"▼",0x0AE9}, {"☜",0x0AEA},
    {"☞",0x0AEB}, {"♣",0x0AEC}, {"♦",0x0AED}, {"♥",0x0AEE}, {"✠",0x0AF0}, {"†",0x0AF1}, {"‡",0x0AF2},
    {"✓",0x0AF3}, {"✗",0x0AF4}, {"♯",0x0AF5}, {"♭",0x0AF6}, {"♂",0x0AF7}, {"♀",0x0AF8}, {"☎",0x0AF9},
    {"⌕",0x0AFA}, {"℗",0x0AFB}, {"‸",0x0AFC}, {"‚",0x0AFD}, {"„",0x0AFE}, {"<",0x0BA3}, {">",0x0BA6},
    {"∨",0x0BA8}, {"∧",0x0BA9}, {"¯",0x0BC0}, {"⊥",0x0BC2}, {"∩",0x0BC3}, {"⌊",0x0BC4}, {"_",0x0BC6},
    {"∘",0x0BCA}, {"⎕",0x0BCC}, {"⊤",0x0BCE}, {"○",0x0BCF}, {"⌈",0x0BD3}, {"∪",0x0BD6}, {"⊃",0x0BD8},
    {"⊂",0x0BDA}, {"⊢",0x0BDC}, {"⊣",0x0BFC}, {"‗",0x0CDF}, {"א",0x0CE0}, {"ב",0x0CE1}, {"ג",0x0CE2},
    {"ד",0x0CE3}, {"ה",0x0CE4}, {"ו",0x0CE5}, {"ז",0x0CE6}, {"ח",0x0CE7}, {"ט",0x0CE8}, {"י",0x0CE9},
    {"ך",0x0CEA}, {"כ",0x0CEB}, {"ל",0x0CEC}, {"ם",0x0CED}, {"מ",0x0CEE}, {"ן",0x0CEF}, {"נ",0x0CF0},
    {"ס",0x0CF1}, {"ע",0x0CF2}, {"ף",0x0CF3}, {"פ",0x0CF4}, {"ץ",0x0CF5}, {"צ",0x0CF6}, {"ק",0x0CF7},
    {"ר",0x0CF8}, {"ש",0x0CF9}, {"ת",0x0CFA}, {"ก",0x0DA1}, {"ข",0x0DA2}, {"ฃ",0x0DA3}, {"ค",0x0DA4},
    {"ฅ",0x0DA5}, {"ฆ",0x0DA6}, {"ง",0x0DA7}, {"จ",0x0DA8}, {"ฉ",0x0DA9}, {"ช",0x0DAA}, {"ซ",0x0DAB},
    {"ฌ",0x0DAC}, {"ญ",0x0DAD}, {"ฎ",0x0DAE}, {"ฏ",0x0DAF}, {"ฐ",0x0DB0}, {"ฑ",0x0DB1}, {"ฒ",0x0DB2},
    {"ณ",0x0DB3}, {"ด",0x0DB4}, {"ต",0x0DB5}, {"ถ",0x0DB6}, {"ท",0x0DB7}, {"ธ",0x0DB8}, {"น",0x0DB9},
    {"บ",0x0DBA}, {"ป",0x0DBB}, {"ผ",0x0DBC}, {"ฝ",0x0DBD}, {"พ",0x0DBE}, {"ฟ",0x0DBF}, {"ภ",0x0DC0},
    {"ม",0x0DC1}, {"ย",0x0DC2}, {"ร",0x0DC3}, {"ฤ",0x0DC4}, {"ล",0x0DC5}, {"ฦ",0x0DC6}, {"ว",0x0DC7},
    {"ศ",0x0DC8}, {"ษ",0x0DC9}, {"ส",0x0DCA}, {"ห",0x0DCB}, {"ฬ",0x0DCC}, {"อ",0x0DCD}, {"ฮ",0x0DCE},
    {"ฯ",0x0DCF}, {"ะ",0x0DD0}, {"ั",0x0DD1}, {"า",0x0DD2}, {"ำ",0x0DD3}, {"ิ",0x0DD4}, {"ี",0x0DD5},
    {"ึ",0x0DD6}, {"ื",0x0DD7}, {"ุ",0x0DD8}, {"ู",0x0DD9}, {"ฺ",0x0DDA}, {"฿",0x0DDF}, {"เ",0x0DE0},
    {"แ",0x0DE1}, {"โ",0x0DE2}, {"ใ",0x0DE3}, {"ไ",0x0DE4}, {"ๅ",0x0DE5}, {"ๆ",0x0DE6}, {"็",0x0DE7},
    {"่",0x0DE8}, {"้",0x0DE9}, {"๊",0x0DEA}, {"๋",0x0DEB}, {"์",0x0DEC}, {"ํ",0x0DED}, {"๐",0x0DF0}, {"๑",0x0DF1},
    {"๒",0x0DF2}, {"๓",0x0DF3}, {"๔",0x0DF4}, {"๕",0x0DF5}, {"๖",0x0DF6}, {"๗",0x0DF7}, {"๘",0x0DF8},
    {"๙",0x0DF9}, {"ㄱ",0x0EA1}, {"ㄲ",0x0EA2}, {"ㄳ",0x0EA3}, {"ㄴ",0x0EA4}, {"ㄵ",0x0EA5}, {"ㄶ",0x0EA6},
    {"ㄷ",0x0EA7}, {"ㄸ",0x0EA8}, {"ㄹ",0x0EA9}, {"ㄺ",0x0EAA}, {"ㄻ",0x0EAB}, {"ㄼ",0x0EAC}, {"ㄽ",0x0EAD},
    {"ㄾ",0x0EAE}, {"ㄿ",0x0EAF}, {"ㅀ",0x0EB0}, {"ㅁ",0x0EB1}, {"ㅂ",0x0EB2}, {"ㅃ",0x0EB3}, {"ㅄ",0x0EB4},
    {"ㅅ",0x0EB5}, {"ㅆ",0x0EB6}, {"ㅇ",0x0EB7}, {"ㅈ",0x0EB8}, {"ㅉ",0x0EB9}, {"ㅊ",0x0EBA}, {"ㅋ",0x0EBB},
    {"ㅌ",0x0EBC}, {"ㅍ",0x0EBD}, {"ㅎ",0x0EBE}, {"ㅏ",0x0EBF}, {"ㅐ",0x0EC0}, {"ㅑ",0x0EC1}, {"ㅒ",0x0EC2},
    {"ㅓ",0x0EC3}, {"ㅔ",0x0EC4}, {"ㅕ",0x0EC5}, {"ㅖ",0x0EC6}, {"ㅗ",0x0EC7}, {"ㅘ",0x0EC8}, {"ㅙ",0x0EC9},
    {"ㅚ",0x0ECA}, {"ㅛ",0x0ECB}, {"ㅜ",0x0ECC}, {"ㅝ",0x0ECD}, {"ㅞ",0x0ECE}, {"ㅟ",0x0ECF}, {"ㅠ",0x0ED0},
    {"ㅡ",0x0ED1}, {"ㅢ",0x0ED2}, {"ㅣ",0x0ED3}, {"ᆨ",0x0ED4}, {"ᆩ",0x0ED5}, {"ᆪ",0x0ED6}, {"ᆫ",0x0ED7},
    {"ᆬ",0x0ED8}, {"ᆭ",0x0ED9}, {"ᆮ",0x0EDA}, {"ᆯ",0x0EDB}, {"ᆰ",0x0EDC}, {"ᆱ",0x0EDD}, {"ᆲ",0x0EDE},
    {"ᆳ",0x0EDF}, {"ᆴ",0x0EE0}, {"ᆵ",0x0EE1}, {"ᆶ",0x0EE2}, {"ᆷ",0x0EE3}, {"ᆸ",0x0EE4}, {"ᆹ",0x0EE5},
    {"ᆺ",0x0EE6}, {"ᆻ",0x0EE7}, {"ᆼ",0x0EE8}, {"ᆽ",0x0EE9}, {"ᆾ",0x0EEA}, {"ᆿ",0x0EEB}, {"ᇀ",0x0EEC},
    {"ᇁ",0x0EED}, {"ᇂ",0x0EEE}, {"ㅭ",0x0EEF}, {"ㅱ",0x0EF0}, {"ㅸ",0x0EF1}, {"ㅿ",0x0EF2}, {"ㆁ",0x0EF3},
    {"ㆄ",0x0EF4}, {"ㆆ",0x0EF5}, {"ㆍ",0x0EF6}, {"ㆎ",0x0EF7}, {"ᇫ",0x0EF8}, {"ᇰ",0x0EF9}, {"ᇹ",0x0EFA},
    {"₩",0x0EFF}, {"Ḃ",0x12A1}, {"ḃ",0x12A2}, {"Ḋ",0x12A6}, {"Ẁ",0x12A8}, {"Ẃ",0x12AA}, {"ḋ",0x12AB},
    {"Ỳ",0x12AC}, {"Ḟ",0x12B0}, {"ḟ",0x12B1}, {"Ṁ",0x12B4}, {"ṁ",0x12B5}, {"Ṗ",0x12B7}, {"ẁ",0x12B8},
    {"ṗ",0x12B9}, {"ẃ",0x12BA}, {"Ṡ",0x12BB}, {"ỳ",0x12BC}, {"Ẅ",0x12BD}, {"ẅ",0x12BE}, {"ṡ",0x12BF},
    {"Ŵ",0x12D0}, {"Ṫ",0x12D7}, {"Ŷ",0x12DE}, {"ŵ",0x12F0}, {"ṫ",0x12F7}, {"ŷ",0x12FE}, {"Œ",0x13BC},
    {"œ",0x13BD}, {"Ÿ",0x13BE}, {"և",0x14A2}, {"։",0x14A3}, {")",0x14A4}, {"(",0x14A5}, {"»",0x14A6},
    {"«",0x14A7}, {"—",0x14A8}, {".",0x14A9}, {"՝",0x14AA}, {",",0x14AB}, {"–",0x14AC}, {"֊",0x14AD},
    {"…",0x14AE}, {"՜",0x14AF}, {"՛",0x14B0}, {"՞",0x14B1}, {"Ա",0x14B2}, {"ա",0x14B3}, {"Բ",0x14B4},
    {"բ",0x14B5}, {"Գ",0x14B6}, {"գ",0x14B7}, {"Դ",0x14B8}, {"դ",0x14B9}, {"Ե",0x14BA}, {"ե",0x14BB},
    {"Զ",0x14BC}, {"զ",0x14BD}, {"Է",0x14BE}, {"է",0x14BF}, {"Ը",0x14C0}, {"ը",0x14C1}, {"Թ",0x14C2},
    {"թ",0x14C3}, {"Ժ",0x14C4}, {"ժ",0x14C5}, {"Ի",0x14C6}, {"ի",0x14C7}, {"Լ",0x14C8}, {"լ",0x14C9},
    {"Խ",0x14CA}, {"խ",0x14CB}, {"Ծ",0x14CC}, {"ծ",0x14CD}, {"Կ",0x14CE}, {"կ",0x14CF}, {"Հ",0x14D0},
    {"հ",0x14D1}, {"Ձ",0x14D2}, {"ձ",0x14D3}, {"Ղ",0x14D4}, {"ղ",0x14D5}, {"Ճ",0x14D6}, {"ճ",0x14D7},
    {"Մ",0x14D8}, {"մ",0x14D9}, {"Յ",0x14DA}, {"յ",0x14DB}, {"Ն",0x14DC}, {"ն",0x14DD}, {"Շ",0x14DE},
    {"շ",0x14DF}, {"Ո",0x14E0}, {"ո",0x14E1}, {"Չ",0x14E2}, {"չ",0x14E3}, {"Պ",0x14E4}, {"պ",0x14E5},
    {"Ջ",0x14E6}, {"ջ",0x14E7}, {"Ռ",0x14E8}, {"ռ",0x14E9}, {"Ս",0x14EA}, {"ս",0x14EB}, {"Վ",0x14EC},
    {"վ",0x14ED}, {"Տ",0x14EE}, {"տ",0x14EF}, {"Ր",0x14F0}, {"ր",0x14F1}, {"Ց",0x14F2}, {"ց",0x14F3},
    {"Ւ",0x14F4}, {"ւ",0x14F5}, {"Փ",0x14F6}, {"փ",0x14F7}, {"Ք",0x14F8}, {"ք",0x14F9}, {"Օ",0x14FA},
    {"օ",0x14FB}, {"Ֆ",0x14FC}, {"ֆ",0x14FD}, {"՚",0x14FE}, {"§",0x14FF}, {"ა",0x15D0}, {"ბ",0x15D1},
    {"გ",0x15D2}, {"დ",0x15D3}, {"ე",0x15D4}, {"ვ",0x15D5}, {"ზ",0x15D6}, {"თ",0x15D7}, {"ი",0x15D8},
    {"კ",0x15D9}, {"ლ",0x15DA}, {"მ",0x15DB}, {"ნ",0x15DC}, {"ო",0x15DD}, {"პ",0x15DE}, {"ჟ",0x15DF},
    {"რ",0x15E0}, {"ს",0x15E1}, {"ტ",0x15E2}, {"უ",0x15E3}, {"ფ",0x15E4}, {"ქ",0x15E5}, {"ღ",0x15E6},
    {"ყ",0x15E7}, {"შ",0x15E8}, {"ჩ",0x15E9}, {"ც",0x15EA}, {"ძ",0x15EB}, {"წ",0x15EC}, {"ჭ",0x15ED},
    {"ხ",0x15EE}, {"ჯ",0x15EF}, {"ჰ",0x15F0}, {"ჱ",0x15F1}, {"ჲ",0x15F2}, {"ჳ",0x15F3}, {"ჴ",0x15F4},
    {"ჵ",0x15F5}, {"ჶ",0x15F6}, {"Ẋ",0x16A3}, {"Ĭ",0x16A6}, {"Ƶ",0x16A9}, {"Ǧ",0x16AA}, {"Ɵ",0x16AF},
    {"ẋ",0x16B3}, {"ĭ",0x16B6}, {"ƶ",0x16B9}, {"ǧ",0x16BA}, {"ǒ",0x16BD}, {"ɵ",0x16BF}, {"Ə",0x16C6},
    {"Ḷ",0x16D1}, {"ḷ",0x16E1}, {"ə",0x16F6}, {"̃",0x1E9F}, {"Ạ",0x1EA0}, {"ạ",0x1EA1}, {"Ả",0x1EA2},
    {"ả",0x1EA3}, {"Ấ",0x1EA4}, {"ấ",0x1EA5}, {"Ầ",0x1EA6}, {"ầ",0x1EA7}, {"Ẩ",0x1EA8}, {"ẩ",0x1EA9},
    {"Ẫ",0x1EAA}, {"ẫ",0x1EAB}, {"Ậ",0x1EAC}, {"ậ",0x1EAD}, {"Ắ",0x1EAE}, {"ắ",0x1EAF}, {"Ằ",0x1EB0},
    {"ằ",0x1EB1}, {"Ẳ",0x1EB2}, {"ẳ",0x1EB3}, {"Ẵ",0x1EB4}, {"ẵ",0x1EB5}, {"Ặ",0x1EB6}, {"ặ",0x1EB7},
    {"Ẹ",0x1EB8}, {"ẹ",0x1EB9}, {"Ẻ",0x1EBA}, {"ẻ",0x1EBB}, {"Ẽ",0x1EBC}, {"ẽ",0x1EBD}, {"Ế",0x1EBE},
    {"ế",0x1EBF}, {"Ề",0x1EC0}, {"ề",0x1EC1}, {"Ể",0x1EC2}, {"ể",0x1EC3}, {"Ễ",0x1EC4}, {"ễ",0x1EC5},
    {"Ệ",0x1EC6}, {"ệ",0x1EC7}, {"Ỉ",0x1EC8}, {"ỉ",0x1EC9}, {"Ị",0x1ECA}, {"ị",0x1ECB}, {"Ọ",0x1ECC},
    {"ọ",0x1ECD}, {"Ỏ",0x1ECE}, {"ỏ",0x1ECF}, {"Ố",0x1ED0}, {"ố",0x1ED1}, {"Ồ",0x1ED2}, {"ồ",0x1ED3},
    {"Ổ",0x1ED4}, {"ổ",0x1ED5}, {"Ỗ",0x1ED6}, {"ỗ",0x1ED7}, {"Ộ",0x1ED8}, {"ộ",0x1ED9}, {"Ớ",0x1EDA},
    {"ớ",0x1EDB}, {"Ờ",0x1EDC}, {"ờ",0x1EDD}, {"Ở",0x1EDE}, {"ở",0x1EDF}, {"Ỡ",0x1EE0}, {"ỡ",0x1EE1},
    {"Ợ",0x1EE2}, {"ợ",0x1EE3}, {"Ụ",0x1EE4}, {"ụ",0x1EE5}, {"Ủ",0x1EE6}, {"ủ",0x1EE7}, {"Ứ",0x1EE8},
    {"ứ",0x1EE9}, {"Ừ",0x1EEA}, {"ừ",0x1EEB}, {"Ử",0x1EEC}, {"ử",0x1EED}, {"Ữ",0x1EEE}, {"ữ",0x1EEF},
    {"Ự",0x1EF0}, {"ự",0x1EF1}, {"̀",0x1EF2}, {"́",0x1EF3}, {"Ỵ",0x1EF4}, {"ỵ",0x1EF5}, {"Ỷ",0x1EF6},
    {"ỷ",0x1EF7}, {"Ỹ",0x1EF8}, {"ỹ",0x1EF9}, {"Ơ",0x1EFA}, {"ơ",0x1EFB}, {"Ư",0x1EFC}, {"ư",0x1EFD},
    {"̉",0x1EFE}, {"̣",0x1EFF}, {"₠",0x20A0}, {"₡",0x20A1}, {"₢",0x20A2}, {"₣",0x20A3}, {"₤",0x20A4},
    {"₥",0x20A5}, {"₦",0x20A6}, {"₧",0x20A7}, {"₨",0x20A8}, {"₩",0x20A9}, {"₪",0x20AA}, {"₫",0x20AB},
    {"€",0x20AC},
    {"～",0xFF5E},
};

static const std::map<QString, quint32> xKeyCodes {
    {"Return", XK_Return}, {"BackSpace", XK_BackSpace}, {"Ctrl", XK_Control_L},
    {"Win", XK_Super_L}, {"Tab", XK_Tab}, {"Alt", XK_Alt_L}, {"Esc", XK_Escape},
    {"Shift", XK_Shift_L}, {"Menu", XK_Menu}, {"Insert", XK_Insert},
    {"Home", XK_Home}, {"End", XK_End}, {"Space", XK_space}, {" ", XK_space},

    {"VolumeUp", XF86XK_AudioRaiseVolume}, {"VolumeDown", XF86XK_AudioLowerVolume}, {"VolumeMute", XF86XK_AudioMute},
    {"PauseSong", XF86XK_AudioPause}, {"NextSong", XF86XK_AudioNext}, {"PrevSong", XF86XK_AudioPrev},

    {"BrightnessUp", XF86XK_KbdBrightnessUp}, {"BrightnessDown", XF86XK_KbdBrightnessDown},

    {"Left", XK_Left}, {"Right", XK_Right}, {"Up", XK_Up}, {"Down", XK_Down},
    {"PgU", XK_Page_Up}, {"PgD", XK_Page_Down},

    {"F1", XK_F1}, {"F2", XK_F2}, {"F3", XK_F3}, {"F4", XK_F4}, {"F5", XK_F5}, {"F6", XK_F6},
    {"F7", XK_F7}, {"F8", XK_F8}, {"F9", XK_F9}, {"F10", XK_F10}, {"F11", XK_F11}, {"F12", XK_F12},

    {"0", XK_0}, {"1", XK_1}, {"2", XK_2}, {"3", XK_3}, {"4", XK_4}, {"5", XK_5},
    {"6", XK_6}, {"7", XK_7}, {"8", XK_8}, {"9", XK_9},

    {"A", XK_A}, {"B", XK_B}, {"C", XK_C}, {"D", XK_D}, {"E", XK_E}, {"F", XK_F},
    {"G", XK_G}, {"H", XK_H}, {"I", XK_I}, {"J", XK_J}, {"K", XK_K}, {"L", XK_L},
    {"M", XK_M}, {"N", XK_N}, {"O", XK_O}, {"P", XK_P}, {"Q", XK_Q}, {"R", XK_R},
    {"S", XK_S}, {"T", XK_T}, {"U", XK_U}, {"V", XK_V}, {"W", XK_W}, {"X", XK_X},
    {"Y", XK_Y}, {"Z", XK_Z},

    {"a", XK_a}, {"b", XK_b}, {"c", XK_c}, {"d", XK_d}, {"e", XK_e}, {"f", XK_f},
    {"g", XK_g}, {"h", XK_h}, {"i", XK_i}, {"j", XK_j}, {"k", XK_k}, {"l", XK_l},
    {"m", XK_m}, {"n", XK_n}, {"o", XK_o}, {"p", XK_p}, {"q", XK_q}, {"r", XK_r},
    {"s", XK_s}, {"t", XK_t}, {"u", XK_u}, {"v", XK_v}, {"w", XK_w}, {"x", XK_x},
    {"y", XK_y}, {"z", XK_z}, {"§",0x00A7},

    {"\\", XK_backslash}, {"'", XK_apostrophe}, {",", XK_comma}, {"-", XK_minus},
    {".", XK_period}, {"/", XK_slash}, {";", XK_semicolon}, {"=", XK_equal},
    {"[", XK_bracketleft}, {"]", XK_bracketright}, /*{"`", XK_grave},*/
    {"<", XK_less},
};

static const std::map<QString, quint32> xUpKeyCodes {
    {"!", XK_exclam}, {"\"", XK_quotedbl}, {"#", XK_numbersign}, {"$", XK_dollar},
    {"%", XK_percent}, {"&", XK_ampersand}, {"(", XK_parenleft},
    {")", XK_parenright}, {"*", XK_asterisk}, {"+", XK_plus},
    {":", XK_colon}, {">", XK_greater}, {"~", XK_asciitilde},
    {"?", XK_question}, {"@", XK_at}, {"_", XK_underscore},
     {":-D", 0},
};

static const QList<Qt::Key> qtKeyCodes {
    {Qt::Key_Backspace, Qt:: Key_Enter, Qt::Key_Return, Qt::Key_Plus,
     Qt::Key_Slash, Qt::Key_Equal
    }
};

static const QList<Qt::Key> qtKeyCodes2 {
    //     √             €               ™              “
    {Qt::Key(8730), Qt::Key(8364), Qt::Key(8482), Qt::Key(8220),
    //     ”            …               ～               ？
     Qt::Key(8221), Qt::Key(8230), Qt::Key(65374), Qt::Key(65311),
    //     ！            ；                 ：
     Qt::Key(65281), Qt::Key(65307), Qt::Key(65306),
    }
};
